home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / win32_1.txt < prev    next >
Encoding:
Text File  |  2000-05-25  |  39.9 KB  |  845 lines

  1.                ***********************************************
  2.                *       A beginners guide to programming      *
  3.                *               the Win32 SDK.                *
  4.                *              By Stephen Haunts              *
  5.                *                                             *
  6.                *                  PART 1                     *
  7.                *        T H E   B A R E   B O N E S          *
  8.                ***********************************************
  9.  
  10. This document serves as a basic introduction to Win32 programming.  If your
  11. interested in games delevopment with DirectX then you will probable write
  12. your programs in a different style to what is explained here for the purposes
  13. of speed.  But even so, you still need to know the basics.  Before you can
  14. get a good grasp of windows programming with the Win32 it is recommended
  15. that you have a fairly strong understanding of writting  DOS applications
  16. in C and/or C++.
  17.  
  18. Although this document covers the bare bones of Win32 programming it is quite
  19. a heavy read if your not familiar with this system.  It may take a while to
  20. get a good grasp of the underlying system behind Win32.  The method of programming
  21. is quite different to that of DOS based programming in C.  The bit that throws
  22. most people is the idea of message maps ect.
  23.  
  24. The some people that the Win32 ways look quite alien and un C like sometimes.
  25. But don't worry.  If I can learn Win32 then you can.
  26.  
  27. This document builds up a simple windows style hello world program to illustrate
  28. the basic concepts to Win32 programming (The source code for this programm will
  29. be bolted on at the end).
  30.  
  31. I will not cover menus and other resources in this document because I dont
  32. want to confuse the issue.  You have to get a grasp of the basics first.
  33. Resources and possiby DirectX will come in different documents.  Hell I may
  34. even make a series of programming articals relating to different aspects
  35. of windows development.  What do you think?
  36.  
  37. If you have any constructive comments about this document (spelling mistakes
  38. aswell) then please mail me at the following address:
  39.        S.B.B.Haunts@herts.ac.uk
  40.  
  41. PLEASE NO FLAMING.  I GET QUITE NASTY IF  PEOPLE FLAME ME FOR SOME STUPID
  42. PETTY REASON WITHOUT GIVING A FULL EXPLAINATION.
  43.  
  44. Why Did I Write This Document ?
  45. -------------------------------
  46.  
  47. Good question.  I my self am personnaly learning to program in windows.  I feel
  48. the best way to get complicated issues to stick in my head are to write short
  49. notes on them.  Because I havn't really found any decent resources on the net
  50. for beginners in Win32 I decided to write up my notes and publish them for you
  51. all to view/download/print for free.  Arn't I nice :-)
  52.  
  53. Who The Hell Am I ?
  54. -------------------
  55.  
  56. My name is Stephen Haunts and I am 20 years old.  I am currently studying for
  57. a BSc Hons Degree in Computer Science at the University of hertfordshire.  I
  58. have just completed my 2nd year of studies and am about to start my 1 years
  59. industry placement, for whome I will be working for Argonaut Software (those
  60. of Star Wing fame on the Super Nintendo console).
  61.  
  62. I have always been a DOS programmer on the PC but my job requires me to train
  63. up in Windows programming and DirectX.
  64.  
  65. OK Here we go folks, have fun :-)
  66.  
  67. Intoduction to windows programming 'WinHello'
  68. ---------------------------------------------
  69.  
  70. Traditionally the introductory program has always been a hello world message.
  71. Under dos such a program could be written in only a few lines but under
  72. windows you are looking at more like a 100 lines of code 'OUCH.' Thats even
  73. worse than a hello world program in assembler :-).
  74.  
  75. When you are working on a large project though the total size of you windows
  76. program may actually end up being less than that of a DOS program (lines of
  77. code that is).
  78.  
  79. The WinMain Procedure
  80. ---------------------
  81.  
  82. Just as every do DOS C program has a procedure called main at its heart, every
  83. windows program has a similar entry point with the title WinMain (and, yes,
  84. this title is case sensative).  Also, just as a DOS C program may include
  85. provisions within the main procedure declaration to retrieve command-line
  86. parameters, the WinMain declaration includes a similar provision in the
  87. lpszCmdParam parameter, even though command-line parameters are rarely used
  88. under windows.
  89.  
  90. However, unlike in DOS programming, the declarations used for WinMain are
  91. not optional and must be declared exactly in the order and form shown,
  92. regardless of whether each specific argument will be used or ingored.
  93.  
  94. Also note that the reserved word PASCAL is used in al exported function declarations,
  95. indicating to the compiler that Pascal rather than C ordering is used for
  96. all arguments(values) pused onto the stack.  While C commonly uses inverted
  97. ordering, placing the least-significant bytes first on the stack, windows
  98. ises pascal ordering which, like Unix, places the most-significant bytes
  99. first.
  100.  
  101. Here is the declaration used for WinMain:
  102.  
  103.         int PASCAL WinMain ( HANDLE hInstance,
  104.                              HANDLE hPrevInstance,
  105.                              LPSTR  lpszCmdParam,
  106.                              int    nCmdShow )
  107.  
  108. Of the four calling arguments, the first two are of primary importance.
  109. The data type HANDLE refers to a 32-bit, unsigned value;  the hInstance and
  110. hPrevInstance are unique identifiers supplied by windowsNT and 95 systems.
  111.  
  112. Inlike DOS applications where where only one program (TSRs excepted) is active
  113. at a time, multitasking systems require unique identification, not only for
  114. each application, but also for each instance of an application of an application
  115. that may be executing.  Ergo, the hInstance and hPrevInstance parameters are
  116. assigned only when an application instance becomes active.  they provide
  117. equivalents of the "task ID" and "process ID" values common in other
  118. multitasking environments.
  119.  
  120. The hPrevInstance (previous instance) identifier is the hInstance identifier
  121. previously assigned to the most recent instance of an application that is
  122. already excuting.  If there is no previous instance of the application
  123. currrently running, which is frequently the case, this argument will by
  124. null(0).  The reason for this second process identifier will be demonstrated
  125. presently.
  126.  
  127. The third prameter, lpszCmdParam, is a long (FAR) pointer to a null-terminated
  128. (ASCIIZ) string containing any command-line parameters passed to the program
  129. instance.
  130.  
  131. The fourth calling parameter, nCmdShow, is simply an integer argument indicating
  132. whether the newly launched application will be displayed as a normal window
  133. or initially displayed as an icon.
  134.  
  135. Next, following the procedure declaration itself, a brief list of local
  136. variable declarations appears.
  137.  
  138.         {
  139.                 static char szAppName[] = "WinHello";
  140.                 HWND        hwnd;
  141.                 MSG         msg;
  142.                 WNDCLASS    wc;
  143.  
  144. The data types used in the declaration will be covered in more detail later
  145. in the document.  Here is a quike rundown:
  146.  
  147.         * HWND identifies a window handle
  148.  
  149.         * MSG identifies a message value
  150.  
  151.         * WNDCLASS refers to a recford structure used to pass a number of
  152.           values relevant to the application's main window.
  153.  
  154.  
  155. Registering a Window Class
  156. --------------------------
  157.  
  158. The first task accomplished within the WinMain procedure depends on the
  159. hPrecInstance argument passed.  If a previous instance of this application is
  160. already active, there's no need to register the window class a second time.
  161. But it's more likely, of course, that this is the first instance of the app-
  162. lication (hPrevinstance is null) and, therefore, the window class definitions
  163. must be assigned and the window class registered.
  164.  
  165. The wc srtructure is defined in Windows.H (which must be included in all
  166. windows applications).  Of the WNDCLASS record fields, the second of the
  167. fields can usually remain unchanged from one application to another
  168.  
  169. The first field is the window-style specification.  In this example, it is
  170. assigned two style flag values combined by ORing bitwise.  These flags are
  171. defined in windows.h as 16-bit constants and shall be explained later.
  172.  
  173. Here the CS_HREDRAW and CS_VREDRAW flags indicate that the following windows
  174. should be redrawn completely anytime the horizontal or vertical size changes.
  175. Thus, for the WinHello demo, if the window size changes, the window display
  176. is completely redrawn, with the hello message string recentered in the new
  177. display.
  178.  
  179.         if (! hPrevInstance )
  180.         {
  181.                 wc.style        = CS_HREDRAW | CS_VREDRAW;
  182.                 cs.lpfnWndProc  = WndProc;
  183.  
  184. The second field in the WNDCLASS structure, lpfnWndProc, is a pointer to the
  185. exported procedure WndProc, in this example - which will handle all windows
  186. messages for this application.  The type prefix lpfn identifies this field
  187. as a "long pointer to function." But realize that these prefic conventions
  188. are provided for the beifit of the programmer.  Tey are not absaolutes, nor do
  189. these designations place any contraints on the compiler.
  190.  
  191. The next two record fields are integers, which are resereved to specify extra
  192. information about the class or window styles.  Commonly, neither is required
  193. and, by default, both are initialized as zeros (0).  Incidentally, the
  194. cb_ prefix stands for count of bytes.
  195.  
  196.                 wc.cbClsExtra   = 0;
  197.                 wc.cbWndExtra   = 0;
  198.                 wc.hInstance    = hInstance;
  199.  
  200. The next field, hInstance, is simply the recipient of the hInstance argument
  201. passed by windows when the program is initially called.  This is also one field
  202. assignment that can be considered constant for all applications.
  203.  
  204. The next three data fields currently assign default values for the
  205. application's icon, cursor, and background color and pattern.
  206.  
  207.                 wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
  208.                 wc.hCursor       = LoadCursor( Null, IDC_ARROW );
  209.                 wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  210.  
  211. The default IDI_APPLICATION specification for the icon assigns the pre-
  212. defined image of a white square with a black border.  The IDC_ARROW cursor
  213. assigns the stock cursor graphic of a slanted arrow.
  214.  
  215. In the third asignment, the hbrBackground field contains the background
  216. colour and pattern used for the application's client region.  The hbr stands
  217. for handle to brush, where "brush" refers to a pixel patterm used to fill or
  218. paint an area.
  219.  
  220. Next, since this application does not have a menu assigned, the menu name is
  221. entered as a null value.  The class name (lpszClassName) is assigned the null-
  222. terminated (ASCIIZ) string defined previously.
  223.  
  224.                 wc.lpszMenuName         = NULL;
  225.                 wc.lpszClassName        = szAppName;
  226.                 RegisterClass( &wc );
  227.         }
  228.  
  229. And last within this conditional subprocess, the RegisterClass function is
  230. called with the wc structure passed as a paramater (by address) to register
  231. this window class definition with the NT/95 operating system.
  232.  
  233. Creating an Application Window
  234. ------------------------------
  235.  
  236. While the previous step, registering a window class, has defined char-
  237. acteristics that are common to all instances of the application, this is not
  238. yet created the application window itself.  Instead, unlike the RegisterClass
  239. function call, which is called only once, every instance of the application
  240. must call the CreateWindow function to produce the actual window display.
  241.  
  242. The handle to the application window that is returned by the CreateWindow
  243. function will be used later as an argument in other function calls as a
  244. unique itentifier for the actual window belonging to the application instance.
  245. But, while many properties of the application class have already been defined,
  246. other properties have already been defined, other properties specific to this
  247. instance of the application have not; they are passed now as parameters to
  248. the CreateWindow function.
  249.  
  250.         hWnd = CreateWindow(
  251.                   szAppName,                  // window class name
  252.                   "Hello, World - NT Style",  // window caption
  253.                   WS_OVERLAPPEDWINDOW,        // window style
  254.                   CW_USERDEFAULT,             // initial X position
  255.                   CW_USERDEFAULT,             // initial Y position
  256.                   CW_USERDEFAULT,             // initial X size
  257.                   CW_USERDEFAULT,             // initial Y size
  258.  
  259. The first two parameters passed are the application class name - the same
  260. ASCIIZ string that was used when the class was registered - and the app-
  261. lication's initial window aption.  If you don't want a caption, then pass
  262. this as null.
  263.  
  264. The third parameter defines the window style, generically, is passed as
  265. WS_OVERlAPPEDWINDOW, a value that is a combination of individual flags
  266. defined in windows.h.
  267.  
  268. The fourth through seventh parameter established the applicaiton window's
  269. initial position and size.  They can be passed as explicit values or, more
  270. often, as CW_USERDEFAULT.  This parameter instructs windows to use the
  271. default values for an overlapped window, positioning each successive
  272. overlapped window at a stepped horizontal and vertical offset from the upper-
  273. left corner of the screen.
  274.  
  275. The next parameter is passed as null for the simple reason that this application
  276. is not associated with a parent window.  Alternatively, if this window were to
  277. be called as a shild process belonging to another aplication, the parent's
  278. window hadle would be passed as a parameter here.
  279.  
  280.                   NULL,                       // parent window handle
  281.                   NULL,                       // window menu handle
  282.  
  283. The ninth parameter using in calling the CreateWindow function is also passed
  284. as null, directing the appliation to use the default system menu.  Note,
  285. however that the menu in question is the windows fram's pull-down menu (upper
  286. -left icon on most window frames), not the menu (or toolbar), which is defined
  287. as an application resource and assigned during application class registration.
  288.  
  289. The tenth calling parameter, which can never be passed as null, is the same
  290. instance handle originally supplied by the NT/95 system.
  291.  
  292.                   hInstance,                  // program instance handle
  293.                   NULL  );                    // creation parameters
  294.  
  295. The final parameter, again null in this example, may in other cases provide
  296. a pointer to additional data for use either by the application window or by
  297. some subsequent process.  In most examples, however, this will be an empty
  298. (null) argument.
  299.  
  300. Now, after CreateWindow has been called, the application window has been
  301. created internally in NT/95 "world view" but does not yet appear on the
  302. actual screen display.  Therefore, the next step is to call the ShowWindow
  303. function, passing as parameters the hwnd value returned by CreateWindow and
  304. the nCmdShow argument supplied when Winmain was initially called.
  305.  
  306.                   ShowWindow( hwnd, nCmdShow );
  307.                   UpdateWindow( hwnd );
  308.  
  309. The ShowWindow function, however, contrary to what you might assume, does only
  310. a portion of the task of creating (painting) the window display.  It is
  311. principally responsible for creating the window frame, caption bar, menu
  312. bar, and minimize/maximize buttons.  But what this function does not create
  313. is the client window area -the display area specific to the application
  314. itself.  Therefore, one more function call is necessary before the window
  315. display is complete: a call to the UpdateWindow function with the hwnd window
  316. handle as an argument (which actually posts a WM_PAINT message to the
  317. application instructing it to repaint its own window area- a process that
  318. will be discussed in a moment.
  319.  
  320. The Message-Handling Loop
  321. -------------------------
  322.  
  323. Windows creates and manages a seperate message queue for each active windows
  324. program instance.  Thus, when and keyboard or mouse event occurs, windows
  325. translates this event into a message value.  This value is placed in the
  326. application's message queue. where it waits until it is retrieved by the
  327. applicationsinstance, which is precisely the purpose of the message-handling
  328. loop.
  329.  
  330. The message handling loop begins by calling the GetMessage function to retrieve
  331. messages from the application instance's message queue.  As long as the message
  332. retrieved is not a WM_QUIT message (0x0012), GetMessage will return a TRUE
  333. (nonzero) result.  The actual message value is returned in the msg structure
  334. which was passed by address.
  335.  
  336.                 while( GetMessage( &msg, NULL, 0, 0) )
  337.                 {
  338.  
  339. The syntax for the GetMessage function is defined as:
  340.  
  341.         BOOL GetMessage( lpMsg, HWND, wMsgFilterMin, wMsgFilterMax )
  342.  
  343. In most cases, only the first parameter is actually used (to return the
  344. message itself).  The remaining three parameters are usually passed as null
  345. or zero.
  346.  
  347. The initial parameter is a pointer to a message structure to receive the
  348. message information retrieved and, subsequently, to pass this data on though
  349. to the TranslateMessage and DispatchMessage functions.  And, obviously, without
  350. this parameter, there would be little point in calling the GetMessage function
  351. at all.
  352.  
  353. The third and fourth parameters provide filter capabilities, restricting the
  354. message types returned.  When both parameters are passed as 0, no filtering
  355. occurs.  Alternatively, constants such as WM_KEYFIRST and WM_KEYLASY could be
  356. passed as filter values to restrict message retrieval to keyboard events or,
  357. by using WM_MOUSEFIRST and WM_MOUSELAST, to retrieve only mouse-related
  358. messages.
  359.  
  360. filters and window selection aside, however, the GetMessage function (together
  361. with the PeekMessage and WaitMessage functions) has another important char-
  362. acteristic.
  363.  
  364. Conventionally, loop statements monopolize the system until terminated, thus
  365. preempting or preventing other operations for the duration of the loop.   And,
  366. in other circumstances -remember this as a caution -even under windows, loop
  367. operations can tie up system resources.
  368.  
  369. The GetMessage function, however, has the ability to preemp the loop operation
  370. to yield control to other applications when no messages are available for the
  371. current application, or when WM_PAINT or WM_TIMER messages directed to other
  372. tasks are available.  Thus, it can give other applications their share of CPU
  373. time to execute.
  374.  
  375. For the present, when the aplication recieved an event messsage (other than
  376. WM_QUIT), the message value is passed.  First, it goes to the windows Translate-
  377. Message function for and keystroke translation that may be specific to the
  378. application.  Then it is passed to the DispatchMessage handler, where the message
  379. information is passed to the next appropriate message-handling procedure (back
  380. to windows, either for immediate handling or, indirectly, for forwarding to the
  381. exported WndProc procedure).
  382.  
  383.                 TranslateMessage( &msg );
  384.                 DispatchMessage( &msg );
  385.              }
  386.  
  387. Finally, when the message-processing loop terminates, the wParam argument from
  388. the final message retrieved is, in turn, returned to the calling application
  389. -the NT/95 desktop itself.
  390.  
  391.              return msg.wParam;
  392.            }
  393.  
  394. Messages and Event-Driven Programming
  395. -------------------------------------
  396.  
  397. In its simplest form, message driven programming (also known as event driven
  398. programming) is a process by which various subprocesses and/ or applications
  399. communicate.  In windows, messages are the process used by windows itself to
  400. manage a multitasking system and to share keyboard, mouse, and other
  401. resources by distributing information to applications, application instances,
  402. and processes within an application.
  403.  
  404. Thus, under windows, instead of applications recieving information directly
  405. from the keyboard or the mouse driver, the NT/95 operating system intercepts
  406. all input information, packaging this information using the MSG message
  407. structure and then forwarding the prepared messages to the appropriate recipients.
  408. In turn, the recipient aplications use TranslateMessage for application-specific
  409. interpretation (particularly accelerator key assignments)  before calling
  410. DispatchMessage to forward individual traffic items to their appropriate handlers.
  411.  
  412. Furthor more, the process descipbed is not limited to keyboard and mouse events.
  413. Instead, this includes all input devices (including ports), as well as messages
  414. generated by application and child subprocesses, windows timers, or, quite
  415. frequently by windows itself.
  416.  
  417. Abstract descriptions, however, provide only a theoretical outline without
  418. really illustrating how these processes function.
  419.  
  420. The Message Record Structure
  421. ----------------------------
  422.  
  423. The MSG (message structure) record type is defined in WinUser.h as
  424.  
  425.         typedef struct tagMSG
  426.         {
  427.                 HWND    hwnd;
  428.                 UINT    message;
  429.                 WPARAM  wParam;
  430.                 LPARAM  lParam;
  431.                 DWORD   time;
  432.                 POINT   pt;
  433.         } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
  434.  
  435. The POINT data type is defined in WinDef.h as:
  436.  
  437.         typedef struct tagPOINT
  438.         {
  439.                 int     x;
  440.                 int     y;
  441.         } POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
  442.  
  443. The message-event fields are used as:
  444.  
  445. - hWnd: The handler of the specific window to which the message is directed.
  446.         Please note that each application is itself composed of a series of
  447.         seperate windows.  These windows include the frame, the caption bar,
  448.         the system menu, and minimize and maximize buttome, as well as the
  449.         application's main display window.  Normally, only messages directed
  450.         to the client window will be forwarded, by the DispatchMessage proc',
  451.         to the application's WndProc procedure.  Messages directed to other
  452.         application windows are generally handled indirectly by NT/95, even
  453.         though this may result, in turn, in further messages being sent to
  454.         the client window.
  455.  
  456. - message: A 16bit value identifying the message.  Constants corresponding to
  457.            all message values are provided though windows.h and begin with the
  458.            WM_ prefix (which stands for windows message). For example, a mouse
  459.            button event message might be identified by the constant WM_LBUTTON.
  460.  
  461. - wParam:  A 32bit (double word) message parameter. The value format and meaning
  462.            depend on the primary event message type.  Variously, the wParam
  463.            argument might convey a coordinate point pair, use the low word value
  464.            to identify a secondary message type, provde some other type of data, of
  465.            be ignored entirely.  In many cases, the wParam value will be treated as
  466.            two seperate word values with different functions.
  467.  
  468. - lParam:  A 32bit (long) message parameter.  The value and meaning of this parameter
  469.            depend on the primary event message type.  Variously, the lParam argument
  470.            might provide a pointer to a string or record structure; break down as a
  471.            group of word, byte, or flag values; or, quite frequently, be completely
  472.            unused.
  473.  
  474. - time:    The double word time value identifies the time the message was placed in the
  475.            message queue.
  476.  
  477. - pt:      This field contains the mouse coordinates at the time the message was
  478.            placed in the message queue (irrespective of the message-event type
  479.            or origin).
  480.  
  481. Note that these last two fields are not passed to the WndProc procedure.
  482. Instead, these two fields are used only by NT/95, principally to resolve any
  483. conflict over the order of events and, of course, to determine where a specific
  484. event should be addressed.
  485.  
  486. The WndProc Procedure
  487. ---------------------
  488.  
  489. The WndProc procedure is the point where each application actually begins to function.
  490. Remember, the WndProc procedure recieves messages indirectly from the NT/95 operating
  491. system, but the WndProc procedure determines the application's response to the
  492. messages received.
  493.  
  494. Previously, when the application window class was registered, the address of
  495. the WndProc subroutine wassed to windows as:
  496.  
  497.         wc.lpfnWndProc = WndProc;
  498.  
  499. And, given this address, windows calls WndProc directly, passing event messages
  500. in the form of four parameters, as:
  501.  
  502.         long FAR PASCAL WndProc( HWND hwnd,
  503.                                  UINT msg,
  504.                                  UINT wParam,
  505.                                  LONG lPARAM )
  506.  
  507. The four calling parameters received correspond to the first four fields of the
  508. message structure described above, beginning with the hwnd parameter.
  509. identifying the window to which the message is directed.  Since most applications
  510. have only one client window that will be addressed thus, this parameter may
  511. seem superfuous.  This parameter will, however, frequently be needed as an
  512. argument for use by other processes.
  513.  
  514. At the present, it's the second calling parameter, msg, that is immediately
  515. crucial and identifies the window event message.  The third and fourth parameters,
  516. wParam and lParam, provide amplifying information to accompany the window
  517. event message.
  518.  
  519. Typically, the WndProc procedure does relatively little or nothing itself
  520. outside the switch...case responding to the msg parameter.  In the hello program
  521. demo, local response is provided for only two event messages: the WM_PAINT
  522. and WM_DESTROY messages.  All other event messages handled are by default
  523. (by the NT/95 operating systems).
  524.  
  525. The first of these two, WM_PAINT, is a message that is generally not issued
  526. directly.  It will be issued indirectly anytime an application window is
  527. created, moved, resized, restored from an icon, uncovered by a change in some
  528. other application window, or something else has occured -in this or in some
  529. other application- to invalidate the client area of the present application.
  530.  
  531. The DOS equivalent of the Hello program would consist principally of a print
  532. statement, possibly with an optional clear screen statement.  For the windows
  533. version, however, there are differences for two main reasons:
  534.  
  535.         * Because the response to the WM_PAINT message is not a one-time
  536.           occurance.
  537.  
  538.         * Because a bit more is accomplished than simply dumping the text
  539.           to the screen.
  540.  
  541. The first requirement, before anything can be written to the client window, is
  542. for the application to retrieve a handle (hdc) to the device context (the output
  543. device or, in this example, the screen).  After the screen update is finished,
  544. this handle will be released by calling the endpaint function.
  545.  
  546.         switch( msg )
  547.         {
  548.                 case WM_PAINT:
  549.                         hdc = BeginPaint( hwnd, &ps );
  550.                         GetClientRect( hwnd, &rect );
  551.  
  552. After retrieving the device context handle, the GetClientRect procedure is called
  553. to retrieve the rect structure with coordinates describing the client window.
  554. The rect structure consists of four fields, which report coordinates for the client
  555. window.  However, the coordinates reported are relative to the client window
  556. itself.  Therefore, the left and top fields are returned as zeros, and the right
  557. and bottom fields return the current width and hight of the client window
  558. (reported in pixels).
  559.  
  560. Once the window coordinates have been retreived, the rect structure can be used
  561. as an argument in the next step to specify the region where the actual message
  562. will be drawn.
  563.  
  564.                 DrawText( hdc, "Hello World", -1, &rect,
  565.                         DT_SINGLELINE | DT_CENTRE | DT_VCENTER );
  566.  
  567. Since print statements, per se, cannot be used in windows (because they are
  568. unsuited for a graphics display environment), the DrawText function is used
  569. instead.  DrawText begins with the hdc argument providing access to the active
  570. display, followed by the string (text) to be drawn.
  571.  
  572. The third parameter, -1, indicates that the string argument is a null-terminated
  573. string.  Alternatively, this parameter could be a value specifying the string
  574. length, with the second parameter an indirect reference to a character array.
  575.  
  576. The fourth argument is the address of the rect structure, identifying an area
  577. where the string will be drawn.  The fifth argument is a combination of flags
  578. that set alignment and ristrict the text drawn to a single display line.
  579.  
  580. Last, the EndPaint function is called, again with the client window handle and
  581. the paint structure (ps) as argument.  This function releases the device context
  582. and validates the now-restored client area, and incidentally, completes the
  583. response to the WM_PAINT message.
  584.  
  585.                 EndPaint( hwnd, &ps );
  586.                 return( 0 );
  587.  
  588. The second application message requiring a local resonse is the WM_DESTROY
  589. message, which is issued when the application is ready to close.  This message
  590. can be generated via several channels.  For this example though it is issued
  591. only if/when the system menu close option is selected.
  592.  
  593.                 case WM_DESTROY:
  594.                         PostQuitMessage(0);
  595.                         break;
  596.  
  597. The WM_DESTROY message is issued to give the application an opportunity to do
  598. any necessary cleanup before shutting down.  Therefore, as circumstances demand
  599. the application response at this point could include provisions for calling a
  600. dialog box to requiest confirmation, for closing/saving files, or for any other
  601. final tasks required for a smooth exit.
  602.  
  603. Finally (unless, of course, termination is to be aborted), the WN_DESTROY
  604. response is completed by calling the PostQuitMessage function, which in turn,
  605. places a WM_QUIT message in the application's message queue to terminate the
  606. message loop in WinMain.
  607.  
  608. Explicit handling has been provided for only two of the messages that might be
  609. sent to this application.  Provisions are also required to return to windows
  610. for procesing all mssages that have not been explicitly handled here, as a
  611. default case.
  612.  
  613.         default:                // is msg unprocessed
  614.            return(              //   return to windows
  615.              DefWindowProc( hwnd, msg, wParam, lParam ) );
  616.        }
  617.        return( NULL );
  618.     }
  619.  
  620. This default provision returns the message -precisely as it was originally
  621. received- to windows, then also returns the results from DefWindowProc to the
  622. windows calling process.  This final provision should be considered standard
  623. for all WndPoc message-handler procedures.
  624.  
  625. For a windows program the .C source code is only a part of the story.  In most
  626. cases, the application will also incorporate an .H header file and, almost
  627. always, a .RES resource file.
  628.  
  629. Here is the complete source code for the hello world program.  You can just
  630. cut out the program from this document and compile it straght off.  The code
  631. should work under any windows compiler with the Win32 libraries.  I have only
  632. tested the code so far under Microsoft Visual C v4.
  633.  
  634. 8<-----------------Cut-out-this-code-and-compile-it--------------------------
  635.  
  636. //===================================//
  637. //            Hello.C                //
  638. //           HELLO WORLD             //
  639. //===================================//
  640.  
  641. #include <windows.h>
  642.  
  643. long APIENTRY WndProc( HWND hwnd,   UINT msg,
  644.                        UINT wParam, LONG lParam )
  645. {
  646.    HDC         hdc;
  647.    PAINTSTRUCT ps;
  648.    RECT        rect;
  649.  
  650.    switch( msg )
  651.    {
  652.       case WM_PAINT:
  653.          hdc = BeginPaint( hwnd, &ps );
  654.          GetClientRect( hwnd, &rect );
  655.          DrawText( hdc, "Hello, World! Muddy Funsters", -1, &rect,
  656.                    DT_SINGLELINE | DT_CENTER | DT_VCENTER );
  657.          EndPaint( hwnd, &ps );
  658.          return( 0 );
  659.  
  660.       case WM_DESTROY:            // message: window being destroyed 
  661.          PostQuitMessage(0);
  662.          break;
  663.  
  664.       default:                        // if msg unproccessed,
  665.                                                         // return to Windows
  666.          return( DefWindowProc( hwnd, msg, wParam, lParam ) );
  667.    }
  668.    return TRUE;
  669. }
  670.  
  671. int APIENTRY WinMain( HANDLE hInstance,    HANDLE hPrevInstance,
  672.                       LPSTR  lpszCmdParam, int    nCmdShow )
  673. {
  674.    static char szAppName[] = "WinHello";
  675.    HWND        hwnd;
  676.    MSG         msg;
  677.    WNDCLASS    wc;
  678.  
  679.    if( ! hPrevInstance )
  680.    {
  681.       wc.style         = CS_HREDRAW | CS_VREDRAW;
  682.       wc.lpfnWndProc   = WndProc;
  683.       wc.cbClsExtra    = 0;
  684.       wc.cbWndExtra    = 0;
  685.       wc.hInstance     = hInstance;
  686.       wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
  687.       wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
  688.       wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  689.       wc.lpszMenuName  = NULL;
  690.       wc.lpszClassName = szAppName;
  691.       RegisterClass( &wc );
  692.    }
  693.    hwnd = CreateWindow(
  694.       szAppName,                                   // window class name       
  695.       "Muddy Funster Software",                    // window caption          
  696.       WS_OVERLAPPEDWINDOW,                         // window style            
  697.       100,                                         // initial X position      
  698.       100,                                         // initial Y position      
  699.       400,                                         // initial X size          
  700.       200,                                         // initial Y size          
  701.       NULL,                                        // parent window handle    
  702.       NULL,                                        // window menu handle      
  703.       hInstance,                                   // program instance handle 
  704.       NULL  );                                     // creation parameters     
  705.    ShowWindow( hwnd, nCmdShow );
  706.    UpdateWindow( hwnd );
  707.  
  708.  
  709.    while( GetMessage( &msg, NULL, 0, 0 ) )
  710.    {
  711.       TranslateMessage( &msg );
  712.       DispatchMessage( &msg );
  713.    }
  714.    return msg.wParam;
  715. }
  716.  
  717. 8<--------------------------------------------------------------------------
  718.  
  719. Windows Conventions and Data Types
  720. ----------------------------------
  721.  
  722. This following section describes some windows NT/95 conventions for naming,
  723. as well as some of the windows data types, data structures, and handle
  724. identifiers.
  725.  
  726. Variable Names and Hungarian Notation
  727. -------------------------------------
  728.  
  729. As programs have become more complex in terms both of size and of the proliferation
  730. of data types, many programmers have adopted a variable-naming convention, which is
  731. commonly fered to as Hungarian notation (named in honor of Microsoft programmer,
  732. Charles Simonyi).
  733.  
  734. Using Hungarian notation, variable names begin with one or more lowercase
  735. letters, which denote the variable type, thus providing an inherent identification.
  736. For example, the prefix h is used to identify a handle, as in hWnd or hDlg,
  737. refering to a window and dialog handles, respectively.  In like fasion, the
  738. prefix lpsz identifies a long pointer to a null-terminated (ASCIIZ) string.
  739.  
  740. The followng table summarizes the Hungarian notation conventions.  These aren't
  741. cast in stone though,  you can come up with variations.
  742.  
  743.              ----------------------------------------------------
  744.              |  PREFIX   |            DATA TYPE                 |
  745.              |-----------+--------------------------------------|
  746.              |    d      | boolean                              |
  747.              |    by     | byte or unsigned char                |
  748.              |    c      | char                                 |
  749.              |    cx/cy  | short used as size                   |
  750.              |    dw     | DWORD, double word or unsigned long  |
  751.              |    fn     | function                             |
  752.              |    h      | handle                               |
  753.              |    i      | int                                  |
  754.              |    l      | long                                 |
  755.              |    n      | short int                            |
  756.              |    s      | string                               |
  757.              |    sz     | ASCIIZ null-terminated string        |
  758.              |    w      | WORD unsigned int                    |
  759.              |    x,y    | short used as coordinates            |
  760.              |--------------------------------------------------|
  761.  
  762. Predefined Constants
  763. --------------------
  764.  
  765. Windows also uses an exclusive list of predefined constants, which are used as
  766. messages, flag values, and other operational parameters.  These constants
  767. values are always uppercase, and most include a two or three letter prefix set
  768. off by an underscore.  Here are some examples.
  769.  
  770.                 CS_HREDRAW      CS_VREDRAW      CW_USERDEFAULT
  771.  
  772.                 DT_CENTER       DT_SINGLELINE   DT_VCENTER
  773.  
  774.                 IDC_ARROW       IDI_APPLICATION WM_DESTROY
  775.  
  776.                 WM_PAINT        WS_OVERLAPPEDWINDOW
  777.  
  778. In the case of constant identifiers, the prefixes indicate the general category
  779. or the constant.  The table below shows the meaning of the prefixes.
  780.  
  781.              ----------------------------------------------------
  782.              |  PREFIX   |            CATEGORY                  |
  783.              |-----------+--------------------------------------|
  784.              |    CS     | Class style                          |
  785.              |    CW     | Create window                        |
  786.              |    DT     | Draw text                            |
  787.              |    IDC    | Cursor ID                            |
  788.              |    IDI    | Icon ID                              |
  789.              |    WM     | Window message                       |
  790.              |    WS     | Window style                         |
  791.              ----------------------------------------------------
  792.  
  793. Data Types
  794. ----------
  795.  
  796. Windows also uses a wide variety of new data types and type identifiers, most
  797. of which are defined in either the WinDef.h or WinUser.H header files.
  798.  
  799.              ------------------------------------------------------
  800.              | DATA TYPE |            MEANING                     |
  801.              |-----------+----------------------------------------|
  802.              |  FAR      | Same as far                            |
  803.              |  PASCAL   | Same as pascal                         |
  804.              |  WORD     | Unsigned integer (16 bits)             |
  805.              |  UINT     | unsigned integer, same as word         |
  806.              |  DWORD    | double word, unsigned long int (32bits)|
  807.              |  LONG     | signed long pointer to character string|
  808.              |  LPSTR    | long (far) pointer to character string |
  809.              ------------------------------------------------------
  810.  
  811. Data Structures
  812. ---------------
  813.  
  814. Similarly, windows adds a variety of new data structures.  Again, most are
  815. defined in either WinDef.h or WinUser.h.  
  816.  
  817.       ---------------------------------------------------------------
  818.       | STRUCTURE    | EXAMPLE |          MEANING                   |
  819.       |--------------+---------+------------------------------------|
  820.       | MSG          |  msg    | Message structure                  |
  821.       | PAINTSTRUCT  |  ps     | Paint structure                    |
  822.       | PT           |  pt     | Point structure (mouse position)   |
  823.       | RECT         |  rect   | Rectangle struc',2 coordinate pairs|
  824.       | WNDCLASS     |  wc     | Window class structure             |
  825.       ---------------------------------------------------------------
  826.  
  827.  
  828. Handle Identifiers
  829. ------------------
  830.  
  831. In like fasion, a variety of handles are defined for use with different
  832. windows elements.  Like constants, the handle types use all uppercase. The
  833. following table shows a few examples.
  834.  
  835.       ----------------------------------------------------------------
  836.       | HANDLE TYPE  | EXAMPLES    |          MEANING                |
  837.       |--------------+-------------+---------------------------------|
  838.       | HANDLE       |hnd or hdl   | Generic handle                  |
  839.       | HWND         |hwnd or hWnd | Window handle                   |
  840.       | HDC          |hdc or hDC   | Device context handle (CRT)     |
  841.       | HBRUSH       |hbr or hBrush| Paint brush handle              |
  842.       | HPEN         |hpen or hPen | Drawing pen handle              |
  843.       ----------------------------------------------------------------
  844.  
  845.